import random
import time
import datetime

from flask import render_template, redirect, request, flash, session, current_app
from flask.helpers import url_for
from flask_login import current_user, login_required, logout_user
from werkzeug.exceptions import abort

from . import user
from .forms import DeleteAccountRequestForm, DeleteAccountForm, UserSetInfoForm, \
                ClickSendEmailCodeForm, EmailChangeForm, PasswordChangeForm, UserImagesUploadsForm, \
                UserArticlePermissionRequestForm, UserArticleWriteForm, PostForm, UserArticleSetForm
from app import db
from app import tools
from app.tools import send_email
from app.models import Post, Images, Role, User_Role_Permission_Request, Article,Tag

# 用户中心页
@user.route("/")
@login_required
def index():
    posts, _ = tools.get_user_post_article()
    return render_template("user/index.html", posts=posts)

# 账户注销请求页
@user.route("/delete_account_request", methods=["GET", "POST"])
def delete_account_request():
    form = DeleteAccountRequestForm()
    if form.validate_on_submit():
        code = random.randint(100000, 999999)
        send_email(
            user=current_user,
            subject="注销账户",
            template="mail/delete_account.html",
            code=code,
        )
        session["code"] = code
        session["code_timeout"] = int(
            time.time()) + current_app.config.get("DELAULT_TIMEOUT_EMAIL_CODE", 300)
        flash("已经为您的邮箱发送验证码，注意查收", "info")
        return redirect(url_for("user.delete_account"))
    return render_template("user/delete_account_request.html", form=form)

# 账户注销页
@user.route("/delete_account", methods=["GET", "POST"])
def delete_account():
    form = DeleteAccountForm()
    if form.validate_on_submit():
        if session["code"] == form.code.data and \
                session["code_timeout"] > int(time.time()) and \
                current_user.verify_password(form.password.data):

            s = "#@#{}{}".format(session["code"], session["code_timeout"])
            current_user.deleted = "true"
            current_user.email = current_user.email + s
            current_user.username = current_user.username + s
            logout_user()
            db.session.commit()

            session["code"] = 0
            session["code_timeout"] = 0

            flash("账户成功注销", "info")
            return redirect(url_for("main.index"))
        else:
            flash("究竟是哪里出错了呢~", "danger")
    return render_template("user/delete_account.html", form=form)

# 用户信息设置页
@user.route("/set", methods=["GET", "POST"])
@login_required
def set():
    form = UserSetInfoForm(current_user)
    if form.validate_on_submit():
        current_user.username = form.username.data
        current_user.intro = form.intro.data
        avatar_img_url = form.avatar_img_url.data
        if avatar_img_url:
            current_user.avatar_img_url = tools.save_user_img("avatar", avatar_img_url)
        current_user.updated_time = datetime.datetime.now()
        db.session.commit()
        flash("修改成功", "success")

    return render_template("user/set.html", form=form)

# 修改绑定邮箱
@user.route("/change_email", methods=["GET", "POST"])
@login_required
def change_email():
    c = ClickSendEmailCodeForm()
    if c.submit1.data and c.validate_on_submit():
        code = random.randint(100000, 999999)
        send_email(
            user=current_user,
            subject="解除邮箱绑定",
            template="mail/change_email.html",
            code=code
        )
        session["code"] = code
        session["code_timeout"] = int(
            time.time()) + current_app.config.get("DELAULT_TIMEOUT_EMAIL_CODE", 300)
    form = EmailChangeForm()
    if form.submit2.data and form.validate_on_submit():
        if session["code"] == form.code.data and \
                session["code_timeout"] > int(time.time()):
            current_user.email = form.email.data
            current_user.updated_time = datetime.datetime.now()
            db.session.commit()

            session["code"] = 0
            session["code_timeout"] = 0
            flash("修改成功", "success")
        else:
            flash("究竟是哪里出错了呢~", "danger")

    return render_template("user/change_email.html", form=form, c=c)

# 修改密码
@user.route("/change_password", methods=["GET", "POST"])
@login_required
def change_password():
    form = PasswordChangeForm()
    if form.validate_on_submit():
        if current_user.verify_password(form.old_password.data):
            current_user.password = form.new_password.data
            current_user.updated_time = datetime.datetime.now()
            db.session.commit()
            flash("修改成功", "success")
        else:
            flash("究竟是哪里出错了呢~", "danger")

    return render_template("user/change_password.html", form=form)

# 发布动态
@user.route("/post", methods=["GET", "POST"])
@login_required
def post():
    form = PostForm()
    if form.validate_on_submit():
        post = Post(body=form.body.data)
        db.session.add(post)
        db.session.commit()
        flash("发布成功", "success")
        form.body.data = ""

    # page = request.args.get("page", 1, int)
    # limit = current_app.config.get("DEFAULT_PAGE_NUMBER", 10)
    # offset = (page-1)*limit
    # posts = Post.query.filter_by(user_id=current_user.id, deleted="false") \
    #     .order_by(Post.created_time.desc()).offset(offset).limit(limit).all()

    posts, page = tools.get_user(Post)
    pages = tools.get_page_all(Post) 

    print("=======================", pages, page)
    return render_template("user/post.html", form=form, posts=posts, pages=pages, page=page)

# 上传图片
@user.route("/upload_img", methods=["GET", "POST"])
@login_required
def upload_img():
    form = UserImagesUploadsForm()
    if form.validate_on_submit():
        for img in form.images.data:
            image = Images(url=tools.save_user_img("upload", img))
            db.session.add(image)
        db.session.commit()
        flash("上传成功", "success")

    imgs, page = tools.get_user(Images)
    pages = tools.get_page_all(Images) 
    return render_template("user/upload_img.html", form=form, imgs=imgs, pages=pages, page=page)

# 发布文章
@user.route("/article", methods=["GET", "POST"])
@login_required
def article():
    if not current_user.is_author_permission():
        flash("权限不足，请先申请", "info")
        return redirect(url_for("user.article_permission_request"))
    
    form = UserArticleWriteForm()
    if form.validate_on_submit():
        article = Article(title=form.title.data,
                            abstract=form.abstract.data,
                            content=form.content.data)
        
        if form.draft.data:
            article.draft = "true"
        
        tags = [r.strip() for r in form.tags.data.split(";") if r != ""]
        for t in tags:
            if len(t) > 16:
                flash("tag len err", "info")
                # return redirect(url_for("user.article"))
                return render_template("user/article.html", form=form)
        article.tags = Tag.insert_tag(tags)

        cover_img = form.cover_img.data
        if cover_img:
            article.cover_url = tools.save_user_img("cover_img", cover_img)

        db.session.add(article)
        db.session.commit()

        form.title.data = ""
        form.cover_img.data = ""
        form.abstract.data = ""
        form.tags.data = ""
        form.content.data = ""
        flash("ok", "success")
    
    return render_template("user/article.html", form=form)

# 写文权限不够，提权请求页
@user.route("/article_permission_request", methods=["GET", "POST"])
@login_required
def article_permission_request():
    if current_user.is_author_permission():
        flash("已经是author", "info")
        return redirect(url_for("user.article"))

    form = UserArticlePermissionRequestForm(current_user)
    if form.validate_on_submit():
        p = User_Role_Permission_Request(title=form.title.data, 
                                            text=form.text.data,
                                            user_id=current_user.id)
        db.session.add(p)
        db.session.commit()
        Role.user_set_permission_author(current_user)
        flash("申请提交成功，注意邮箱", "success")

    return render_template("user/article_permission_request.html", form=form)

# 草稿管理列表
@user.route("/article/manager", methods=["GET", "POST"])
@login_required
def article_manager():
    posts = Article.query.filter_by(deleted="false", user_id=current_user.id, draft="true") \
        .order_by(Article.created_time.desc()).all()
    return render_template("user/article_manager.html", posts=posts)

# 草稿管理页
@user.route("/article/manager/<int:aid>", methods=["GET", "POST"])
@login_required
def article_manager_page(aid):
    post = Article.query.filter_by(deleted="false", id=aid, draft="true") \
        .order_by(Article.created_time.desc()).first()
    if not post:
        abort(404)

    form = UserArticleSetForm()
    if request.method == "GET":
        form.title.data = post.title
        form.abstract.data = post.abstract
        form.content.data = post.content
        form.cover_img.data = post.cover_url
        form.tags.data = "; ".join([t.name for t in post.tags.all()])

    if form.validate_on_submit():
        post.title = form.title.data
        post.abstract = form.abstract.data
        post.content = form.content.data
        url, ok = tools.check_img_url(form.cover_img.data)
        if ok:
            post.cover_url = url

        if form.draft.data:
            post.draft = "true"
        else:
            post.draft = "false"
        
        tags = [r.strip() for r in form.tags.data.split(";") if r != ""]
        for t in tags:
            if len(t) > 16:
                flash("tag len err", "info")
                return redirect(url_for("user.article_manager_page", aid=post.id))
        post.tags = Tag.insert_tag(tags)

        post.updated_time = datetime.datetime.now()

        db.session.commit()

        form.title.data = ""
        form.cover_img.data = ""
        form.abstract.data = ""
        form.tags.data = ""
        form.content.data = ""
        flash("ok", "success")
        return redirect(url_for("user.article_manager"))

    return render_template("user/article_manager_page.html", post=post, form=form)
